package com.offics.loan.application.service;

import com.offics.loan.application.dto.repayment.RepayRequest;
import com.offics.loan.application.dto.repayment.RepayResponse;
import com.offics.loan.application.dto.repayment.RepaymentPlanResponse;
import com.offics.loan.application.dto.repayment.RepaymentRecordResponse;
import com.offics.loan.domain.entity.RepaymentPlan;
import com.offics.loan.domain.entity.RepaymentRecord;
import com.offics.loan.domain.repository.RepaymentPlanRepository;
import com.offics.loan.domain.repository.RepaymentRecordRepository;
import com.offics.loan.domain.service.RepaymentDomainService;
import com.offics.loan.infrastructure.exception.BusinessException;
import com.offics.loan.infrastructure.common.ResultCode;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 还款应用服务
 */
@Service
@RequiredArgsConstructor
public class RepaymentApplicationService {

    private final RepaymentPlanRepository repaymentPlanRepository;
    private final RepaymentRecordRepository repaymentRecordRepository;
    private final RepaymentDomainService repaymentDomainService;

    /**
     * 还款
     *
     * @param request 还款请求
     * @return 还款响应
     */
    public RepayResponse repay(RepayRequest request) {
        RepaymentRecord record = repaymentDomainService.repay(
                request.getUserId(),
                request.getLoanId(),
                request.getRepaymentPlanId(),
                request.getAmount(),
                request.getRepayType(),
                request.getBankCardId()
        );

        RepayResponse response = new RepayResponse();
        BeanUtils.copyProperties(record, response);
        response.setRepayTypeText(record.getRepayTypeText());
        response.setStatusText(getRepaymentStatusText(record.getStatus()));
        return response;
    }

    /**
     * 获取贷款的还款计划列表
     *
     * @param loanId 贷款ID
     * @return 还款计划列表
     */
    public List<RepaymentPlanResponse> getRepaymentPlanList(Long loanId) {
        List<RepaymentPlan> plans = repaymentDomainService.getLoanRepaymentPlans(loanId);
        return plans.stream().map(this::convertToRepaymentPlanResponse).collect(Collectors.toList());
    }

    /**
     * 获取用户的还款计划列表
     *
     * @param userId 用户ID
     * @return 还款计划列表
     */
    public List<RepaymentPlanResponse> getUserRepaymentPlanList(Long userId) {
        List<RepaymentPlan> plans = repaymentDomainService.getUserRepaymentPlans(userId);
        return plans.stream().map(this::convertToRepaymentPlanResponse).collect(Collectors.toList());
    }

    /**
     * 获取还款计划详情
     *
     * @param id 还款计划ID
     * @return 还款计划详情
     */
    public RepaymentPlanResponse getRepaymentPlanDetail(Long id) {
        RepaymentPlan plan = repaymentPlanRepository.findById(id)
                .orElseThrow(() -> new BusinessException(ResultCode.REPAYMENT_PLAN_NOT_FOUND));
        return convertToRepaymentPlanResponse(plan);
    }

    /**
     * 获取用户的还款记录列表
     *
     * @param userId 用户ID
     * @return 还款记录列表
     */
    public List<RepaymentRecordResponse> getRepaymentRecordList(Long userId) {
        List<RepaymentRecord> records = repaymentDomainService.getUserRepaymentRecords(userId);
        return records.stream().map(this::convertToRepaymentRecordResponse).collect(Collectors.toList());
    }

    /**
     * 获取贷款的还款记录列表
     *
     * @param loanId 贷款ID
     * @return 还款记录列表
     */
    public List<RepaymentRecordResponse> getLoanRepaymentRecordList(Long loanId) {
        List<RepaymentRecord> records = repaymentDomainService.getLoanRepaymentRecords(loanId);
        return records.stream().map(this::convertToRepaymentRecordResponse).collect(Collectors.toList());
    }

    /**
     * 获取还款记录详情
     *
     * @param id 还款记录ID
     * @return 还款记录详情
     */
    public RepaymentRecordResponse getRepaymentRecordDetail(Long id) {
        RepaymentRecord record = repaymentRecordRepository.findById(id)
                .orElseThrow(() -> new BusinessException(ResultCode.REPAYMENT_RECORD_NOT_FOUND));
        return convertToRepaymentRecordResponse(record);
    }

    /**
     * 转换为还款计划响应
     *
     * @param plan 还款计划
     * @return 还款计划响应
     */
    private RepaymentPlanResponse convertToRepaymentPlanResponse(RepaymentPlan plan) {
        RepaymentPlanResponse response = new RepaymentPlanResponse();
        BeanUtils.copyProperties(plan, response);
        response.setStatusText(getRepaymentPlanStatusText(plan.getStatus()));
        return response;
    }

    /**
     * 转换为还款记录响应
     *
     * @param record 还款记录
     * @return 还款记录响应
     */
    private RepaymentRecordResponse convertToRepaymentRecordResponse(RepaymentRecord record) {
        RepaymentRecordResponse response = new RepaymentRecordResponse();
        BeanUtils.copyProperties(record, response);
        response.setRepayTypeText(record.getRepayTypeText());
        response.setStatusText(getRepaymentStatusText(record.getStatus()));
        return response;
    }

    /**
     * 获取还款计划状态文本
     *
     * @param status 状态
     * @return 状态文本
     */
    private String getRepaymentPlanStatusText(Integer status) {
        if (status == null) {
            return "";
        }
        switch (status) {
            case 0:
                return "未还";
            case 1:
                return "已还";
            case 2:
                return "逾期";
            default:
                return "未知";
        }
    }

    /**
     * 获取还款状态文本
     *
     * @param status 状态
     * @return 状态文本
     */
    private String getRepaymentStatusText(Integer status) {
        if (status == null) {
            return "";
        }
        switch (status) {
            case 0:
                return "处理中";
            case 1:
                return "成功";
            case 2:
                return "失败";
            default:
                return "未知";
        }
    }
}